'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Public Class IcqMessageService
    Inherits ContextService
    Implements Interfaces.IMessageService, Interfaces.IOfflineMessageService

    Public Event MessageReceived(ByVal sender As Object, ByVal e As Interfaces.MessageEventArgs) Implements Interfaces.IMessageService.MessageReceived

    Public Sub New(ByVal context As Interfaces.IContext)
        MyBase.New(context)

        Dim connector As IcqConnector = TryCast(context.GetService(Of Interfaces.IConnector)(), IcqConnector)

        If connector Is Nothing Then Throw New InvalidCastException("Context Connector Service must be of Type IcqConnector")

        connector.RegisterSnacHandler(Of DataTypes.Snac0407)(&H4, &H7, New Action(Of DataTypes.Snac0407)(AddressOf AnalyseSnac0407))
        connector.RegisterSnacHandler(Of DataTypes.Snac1503)(&H15, &H3, New Action(Of DataTypes.Snac1503)(AddressOf AnalyseSnac1503))
    End Sub

    Private Sub AnalyseSnac0407(ByVal snac As DataTypes.Snac0407)
        Dim msg As IcqMessage

        Dim senderId As String
        Dim messageText As String

        Dim sender As Interfaces.IContact
        Dim recipient As Interfaces.IContact

        Try
            senderId = snac.ScreenName
            messageText = snac.MessageData.MessageText

            sender = Context.GetService(Of Interfaces.IStorageService).GetContactByIdentifier(senderId)
            recipient = Context.Identity

            msg = New IcqMessage(sender, recipient, messageText)

            RaiseEvent MessageReceived(Me, New Interfaces.MessageEventArgs(msg))
        Catch ex As Exception
            Core.Kernel.Exceptions.PublishException(ex)
        End Try
    End Sub

    Private Sub AnalyseSnac1503(ByVal snac As DataTypes.Snac1503)
        Dim msg As IcqOfflineMessage

        Dim senderId As String
        Dim messageText As String

        Dim sender As Interfaces.IContact
        Dim recipient As Interfaces.IContact

        Try
            Select Case snac.MetaData.MetaResponse.ResponseType
                Case DataTypes.MetaResponseType.OfflineMessageResponse
                    Dim resp As DataTypes.OfflineMessageResponse = DirectCast(snac.MetaData.MetaResponse, DataTypes.OfflineMessageResponse)

                    senderId = CStr(resp.ClientUin)
                    messageText = resp.MessageText

                    sender = Context.GetService(Of Interfaces.IStorageService).GetContactByIdentifier(senderId)
                    recipient = Context.Identity

                    msg = New IcqOfflineMessage(sender, recipient, messageText, resp.DateSent)

                    RaiseEvent MessageReceived(Me, New Interfaces.MessageEventArgs(msg))

                Case DataTypes.MetaResponseType.EndOfOfflineMessageResponse
                    RaiseEvent AllOfflineMessagesReceived(Me, System.EventArgs.Empty)
            End Select
        Catch ex As Exception
            Core.Kernel.Exceptions.PublishException(ex)
        End Try
    End Sub

    Public Sub SendMessage(ByVal message As Interfaces.IMessage) Implements Interfaces.IMessageService.SendMessage
        Dim dataOut As DataTypes.Snac0406

        dataOut = New DataTypes.Snac0406
        dataOut.Channel = DataTypes.MessageChannel.Channel1PlainText
        dataOut.CookieID = System.Environment.TickCount
        dataOut.RequestAnAckFromServer = False
        dataOut.ScreenName = message.Recipient.Identifier
        dataOut.StoreMessageIfRecipientIsOffline = True

        dataOut.MessageData.MessageText = message.Text

        Dim transfer As IIcqDataTranferService = DirectCast(Context.GetService(Of Interfaces.IConnector)(), IIcqDataTranferService)
        transfer.Send(dataOut)
    End Sub

    Public Sub DeleteOfflineMessages() Implements Interfaces.IOfflineMessageService.DeleteOfflineMessages
        Dim dataOut As DataTypes.Snac1502

        dataOut = New DataTypes.Snac1502

        Dim req As DataTypes.DeleteOfflineMessagesRequest
        req = New DataTypes.DeleteOfflineMessagesRequest
        req.ClientUin = CLng(Context.Identity.Identifier)

        dataOut.MetaData.MetaRequest = req

        Dim transfer As IIcqDataTranferService = DirectCast(Context.GetService(Of Interfaces.IConnector)(), IIcqDataTranferService)
        transfer.Send(dataOut)
    End Sub

    Public Sub RequestOfflineMessages() Implements Interfaces.IOfflineMessageService.RequestOfflineMessages
        Dim dataOut As DataTypes.Snac1502

        dataOut = New DataTypes.Snac1502

        Dim req As DataTypes.OfflineMessageRequest
        req = New DataTypes.OfflineMessageRequest
        req.ClientUin = CLng(Context.Identity.Identifier)

        dataOut.MetaData.MetaRequest = req

        Dim transfer As IIcqDataTranferService = DirectCast(Context.GetService(Of Interfaces.IConnector)(), IIcqDataTranferService)
        transfer.Send(dataOut)
    End Sub

    Public Event AllOfflineMessagesReceived(ByVal sender As Object, ByVal e As System.EventArgs) Implements Interfaces.IOfflineMessageService.AllOfflineMessagesReceived
End Class

